﻿using GoodStuff.Security;
using NUnit.Framework;

namespace GoodStuff.UnitTests
{
    [TestFixture]
    public class SecurePasswordTest
    {
        [Test]
        public void InitializePasswordAndValidate()
        {
            SecurePassword pw = new SecurePassword("Hello");
            Assert.IsTrue(pw.Validate("Hello"));
        }

        [Test]
        public void InitializePasswordAndValidateFailure()
        {
            SecurePassword pw = new SecurePassword("Hello");
            Assert.IsFalse(pw.Validate("SomethingElse"));
        }

        [Test]
        public void InitializePersistAndValidate()
        {
            SecurePassword pw = new SecurePassword("Hello");

            string hash = pw.SaltedHash;
            int salt = pw.Salt;

            SecurePassword pw2 = new SecurePassword(hash, salt);


            Assert.IsTrue(pw2.Validate("Hello"));
        }

        [Test]
        public void AssertPasswordNotClear()
        {
            SecurePassword pw = new SecurePassword("Hello");

            Assert.AreNotSame(pw.SaltedHash, "Hello");
        }


        [Test]
        public void AssertSamePasswordsDoNotShareHashOrSalt()
        {
            SecurePassword pw = new SecurePassword("Hello");
            SecurePassword pw2 = new SecurePassword("Hello");

            Assert.AreNotSame(pw.SaltedHash, pw2.SaltedHash);
            Assert.AreNotSame(pw.Salt, pw2.Salt);
        }

        [Test]
        public void TestStrongPasswords()
        {
            Assert.IsTrue(SecurePassword.IsStrong("Hello_There"));
            Assert.IsTrue(SecurePassword.IsStrong("Hello7There"));
            Assert.IsTrue(SecurePassword.IsStrong("Hello&There"));
            Assert.IsTrue(SecurePassword.IsStrong("HelloThere("), "mixed");
            Assert.IsFalse(SecurePassword.IsStrong("HelloThere"), "just letters");
            Assert.IsFalse(SecurePassword.IsStrong("me"), "way too short");
            Assert.IsFalse(SecurePassword.IsStrong("1234567"), "just numbers");
            Assert.IsFalse(SecurePassword.IsStrong("Admin"), "mixed, but too short");
            Assert.IsFalse(SecurePassword.IsStrong("root"), "too short");
            Assert.IsFalse(SecurePassword.IsStrong("rootrootrootroot"), "All lowercase");
            Assert.IsFalse(SecurePassword.IsStrong("ROOTROOTROOTROOT"), "All uppercase");
        }

        [Test]
        public void NullPasswordIsNotStrong()
        {
            Assert.IsFalse(SecurePassword.IsStrong(null));
        }

        [Test]
        public void EmptyPasswordIsNotStrong()
        {
            Assert.IsFalse(SecurePassword.IsStrong(""));
        }

        [Test]
        public void AllLowerWithSymbolsIsNotStrong()
        {
            Assert.IsFalse(SecurePassword.IsStrong("rootroot1234_"));
        }

        [Test]
        public void AllUpperWithSymbolsIsNotStrong()
        {
            Assert.IsFalse(SecurePassword.IsStrong("ROOTROOT1234_"));
        }

        [Test]
        public void GenerateStrongPassword()
        {
            string pw = SecurePassword.CreateRandomPassword(10);
            Assert.AreEqual(10, pw.Length);

            Assert.IsTrue(SecurePassword.IsStrong(pw), "Generated password '" + pw + "'should be strong");
        }
    }
}
